package com.cloud.prac.endecrypt;

import cn.hutool.core.codec.Base64;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

/**
 * 对称加密：一个密钥完成加解密
 * DES/AES
 */
@Slf4j
public class DesTest {

    /**
     * 加密类型（加密类型及填充模式）;默认 ECB/PKCS5Padding
     * ECB：密码块并行处理；同样原文会产生同样密文
     * CBC：密码块串行处理；
     */
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    // 加密算法
    private static final String ALGORITHM = "AES";
    // des 加密key步长必须是8位 ; aes 步长是16位
    private static final String KEY = "1234567812345678";

    public static void main(String[] args) throws Exception {
        String str = "hello world";
        String encryptStr = DesEncrypt(str);
        log.info("encryptStr:{}", encryptStr);
        String decrypt = DesDecrypt(encryptStr);
        log.info("decryptStr:{}", decrypt);

    }

    private static String DesEncrypt(String str) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        // 密钥规则；算法
        SecretKeySpec sks = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        IvParameterSpec iv = new IvParameterSpec("1234567812345678".getBytes());
        // 加解密模式；密钥规则；iv向量
        cipher.init(Cipher.ENCRYPT_MODE, sks, iv);
        byte[] bytes = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));
        // 有负数 ascii 码解析不出来 会乱码
        log.info(new String(bytes));
        // 结合base64 解决乱码问题
        String encode = Base64.encode(bytes);
        log.info(encode);
        log.info("=========>");
        return encode;
    }

    private static String DesDecrypt(String str) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        // des 加密key步长必须是8位
        // 密钥；算法
        SecretKeySpec sks = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        IvParameterSpec iv = new IvParameterSpec("1234567812345678".getBytes());
        // 加解密模式；密钥规则；iv向量
        cipher.init(Cipher.DECRYPT_MODE, sks, iv);
        byte[] bytes = cipher.doFinal(Base64.decode(str));
        // ascii 码有负数 解析不出来 有乱码
        return new String(bytes, StandardCharsets.UTF_8);
    }

}
